home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / ImageWriter--Chooser snooper / ChooserSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-15  |  11.4 KB  |  399 lines  |  [TEXT/MPS ]

  1. /*
  2.     ChooserSupport.c - C code for PACK and LDEF resources used by the Chooser.
  3.     
  4.     Copyright © 1992-1996 Apple Computer, Inc.
  5.     All rights reserved.
  6.  
  7.     10/20/93        dmh        Added GetChooserPopUpValue routine.
  8.     12/20/93        dmh        Sync'd with the shipping 1.0b3 GX driver.
  9.      8/26/94        dmh        Sync'd with the shipping 1.0.1 GX driver.
  10.      8/26/94        dmh        Universalized code.
  11.      6/14/96        cn        Updated to support Universal Interfaces 2.1.
  12. */
  13.  
  14. #include <Types.h>
  15. #include <QuickDraw.h>
  16. #include <Fonts.h>
  17. #include <Lists.h>
  18. #include <Devices.h>
  19. #include <Resources.h>
  20. #include <Script.h>
  21. #include <ToolUtils.h>
  22. #include <LowMem.h>
  23.  
  24. #include <GXGraphics.h>
  25. #include <GXPrinterDrivers.h>
  26.  
  27. #include <Strings.h>
  28. #include <StdIO.h>
  29.  
  30. extern short GetChooserPopUpValue(Str255 itemStr);
  31.  
  32.  
  33. // Redefine these calls so that the linker won't give us
  34. // code->data ref errors when we use sprintf.     
  35.  
  36. size_t fwrite (const void *buff, size_t elemSize, size_t size, FILE *aFile) { return 0; }
  37. int _flsbuf(unsigned char aChar, FILE *aFile){ return 0; }
  38.  
  39.  
  40. // ------------------------------------------------------------------------
  41. // INTERNAL DEFINES
  42. // ------------------------------------------------------------------------
  43. // Chooser initialize message selector
  44. #define initializeMsg    11
  45.  
  46. // Icon Suite support
  47. #define ttNone        0x0000
  48. #define ttDisabled    0x0001
  49. #define    ttOffline    0x0002
  50. #define ttOpen        0x0003
  51. #define ttSelected     0x4000
  52. #define ttSelectedDisabled    (ttSelected + ttDisabled)
  53. #define ttSelectedOffline    (ttSelected + ttOffline)
  54. #define ttSelectedOpen        (ttSelected + ttOpen)
  55.  
  56. #define ttLabel0    0x0000
  57. #define ttLabel1    0x0100
  58. #define ttLabel2    0x0200
  59. #define ttLabel3    0x0300
  60. #define ttLabel4    0x0400
  61. #define ttLabel5    0x0500
  62. #define ttLabel6    0x0600
  63. #define ttLabel7    0x0700
  64. pascal OSErr PlotIconSuite(const Rect * theRect, short align, short iconTransform, Handle cIcon)
  65.     = {0x303C, 0x0603, 0xABC9};
  66.  
  67. // Copy of the DrawText trap
  68. pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
  69.     = 0xA885; 
  70.  
  71. // ------------------------------------------------------------------------
  72. // MAIN CODE FOR PACK
  73. // ------------------------------------------------------------------------
  74. pascal OSErr Device(short message, short caller, StringPtr objName, 
  75.                     StringPtr zoneName, ListHandle theList, long p2)
  76. {
  77.     
  78.     OSErr            anErr = noErr;
  79.     extern Str31     gDriverName;
  80.     StringPtr        pDriverName = gDriverName;
  81.     extern gxJob    gJob;                        // Declared in our .a file.
  82.     gxJob            *pJob = &gJob;
  83.  
  84.     if (message == initializeMsg)    // InitializeMsg--start up GX
  85.     {
  86.         FCBPBRec    pb;
  87.  
  88.     /*
  89.         Get the name of our driver for GXHandleChooserMessage.
  90.         (The user may have renamed us.)
  91.     */
  92.         pb.ioCompletion     = nil;
  93.         pb.ioNamePtr         = pDriverName;
  94.         pb.ioVRefNum         = 0;
  95.         pb.ioRefNum         = CurResFile();
  96.         pb.ioFCBIndx         = 0;
  97.         anErr = PBGetFCBInfo(&pb, false);
  98.  
  99.     /*
  100.         Clear *pJob, because it hasn't been initialized yet.  That doesn't
  101.         happen until we pass GXHandleChooserMessage an initializeMsg.
  102.     */
  103.         *pJob = nil;
  104.  
  105.     /*
  106.         We need to initialize GX printing so that we can call
  107.         GXHandleChooserMessage.  Since printing requires a graphics
  108.         client, call GXEnterGraphics first.  If there are errors,
  109.         (for example, due to memory limitations), post an alert.
  110.     */
  111.         if (anErr == noErr)
  112.         {
  113.             GXEnterGraphics();
  114.             anErr = GXGetGraphicsError(nil);
  115.             if (anErr == noErr)
  116.             {
  117.                 anErr = GXInitPrinting();
  118.                 if (anErr != noErr)
  119.                     GXExitGraphics();
  120.             }
  121.                 
  122.             if (anErr != noErr)
  123.                 StopAlert(-4095, nil);
  124.         }
  125.     }
  126.  
  127. /*
  128.     If the Chooser hasn't created a job yet, do nothing unless we were
  129.     sent an initializeMsg.  In its default implementation of
  130.     GXHandleChooserMessage, QuickDraw GX will create the job for our
  131.     driver when it receives an initializeMsg.  It will store a reference
  132.     to it in our pJob pointer.
  133.     
  134.     For all other messages, if a job has been created, call
  135.     GXHandleChooserMessage to handle things.
  136. */
  137.     if (anErr == noErr)
  138.     {
  139.         if ((*pJob != nil) || (message == initializeMsg))
  140.         {
  141.             anErr = GXHandleChooserMessage(pJob, pDriverName, message, caller, objName, zoneName, theList, p2);
  142.  
  143.         /*
  144.             Drop into the debugger and display info about the current
  145.             "Connect via" menu item.
  146.         */
  147.             if (anErr == noErr)
  148.             {
  149.                 Str255        pStr, itemStr;
  150.                 short        itemNum = GetChooserPopUpValue(itemStr);
  151.  
  152.                 p2cstr(itemStr);
  153.                 pStr[0] = sprintf((char *) &pStr[1], "menu item = %d, item string = \"%s\".", itemNum, itemStr);
  154.                 DebugStr(pStr);
  155.             }
  156.  
  157.         /*
  158.             If we just got a terminateMsg, and p2 is also terminateMsg, the
  159.             Chooser is closing.  QuickDraw GX just disposed of the gxJob it
  160.             created earlier when GXHandleChooserMessage was passed
  161.             initializeMsg, so we just need to call GXExitPrinting and
  162.             GXExitGraphics to clean up.
  163.             
  164.             Note that we must test the p2 parameter, because the Chooser
  165.             can also send terminateMsg when it wants to empty the device
  166.             list, but not dispose of us.  For example, this will happen
  167.             when the user turns off AppleTalk in the Chooser.
  168.         */
  169.             if ((message == terminateMsg) && (p2 == terminateMsg))
  170.             {
  171.                 GXExitPrinting();
  172.                 GXExitGraphics();
  173.             }
  174.         }
  175.     }
  176.         
  177.     return(anErr);
  178.     
  179. } // Device
  180.  
  181.  
  182. /*    --------------------------------------------------------
  183.     This routine returns the item number and label of the
  184.     current "Connect via" menu item.  If the Chooser window
  185.     is closed, it returns 0 for the item number and "" for
  186.     the item string.
  187.     
  188.     NOTE: This routine is only valid once the Chooser's
  189.     initialize message has been forwarded to
  190.     GXHandleChooserMessage.  The pop-up control is appended
  191.     to the Chooser DITL at that time, so trying to access it
  192.     earlier is not possible.
  193.  
  194.     -------------------------------------------------------- */
  195.  
  196. short GetChooserPopUpValue(Str255 itemStr)
  197. {
  198.     WindowPtr        chooserWindow;
  199.     short            itemNum, popUpItem, itemKind;
  200.     ControlHandle    ctlHandle;
  201.     Rect            itemRect;
  202.     MenuHandle        thePopupMenu;
  203.  
  204. /* If the Chooser window is closed, we'll return 0 for the
  205.    item number and "" for the item string.  This would be
  206.    the case if we came here after being passed a terminate
  207.    event caused by closing the Chooser window. */
  208.  
  209.     *itemStr = 0;
  210.     itemNum = 0;
  211.  
  212.  
  213. /* Get the Chooser window, and count its DITL items.  The
  214.    pop-up menu control was the last control added, so we
  215.    just need to access the last DITL item.  The currently
  216.    selected menu item is stored as the control's value,
  217.    and the pop-up's MenuHandle is the first long in the
  218.    control's data handle.  Return the selected menu item
  219.    and its name. */
  220.  
  221.     chooserWindow = FrontWindow();
  222.     
  223.     if (chooserWindow != nil)
  224.     {
  225.         popUpItem = CountDITL(chooserWindow);
  226.         GetDItem(chooserWindow, popUpItem, &itemKind, (Handle *) &ctlHandle, &itemRect);
  227.         itemNum = GetCtlValue(ctlHandle);
  228.         
  229.         thePopupMenu = *(MenuHandle *) *(*ctlHandle)->contrlData;
  230.         GetItem(thePopupMenu, itemNum, itemStr);
  231.     }
  232.     
  233.     return itemNum;
  234. }
  235.  
  236.  
  237. // ------------------------------------------------------------------------
  238. // ENTRY POINT FOR LDEF
  239. // ------------------------------------------------------------------------
  240.  
  241. pascal void LDEF(
  242.     short         message,        // What operation to perform on list
  243.     Boolean     select,            // Is this cell to be selected or not?
  244.     Rect        *theRect,        // Rectangle of this cell, clipped to window
  245.     Cell        theCell,        // Which cell this is
  246.     short        dataOffset,        // Offset into data for this cell
  247.     short        dataLen,        // Length of data for this cell
  248.     ListHandle    theList)        // The list to act upon
  249. /*
  250.     An LDEF that works in two modes:
  251.         - if the first two characters of the cell are valid AppleTalk NBP names (ie, not ≈ ≈)
  252.           then the LDEF is just a basic text LDEF
  253.         - otherwise, it assumes the data is part of a PortListRec, which is
  254.           a structure for icons with text underneath
  255. */
  256.  
  257. {
  258. #pragma unused (theCell, dataLen)
  259.  
  260.     gxPortListRec        theCellContents;
  261.     Rect                iconRect;
  262.     unsigned char        hiliteMode;
  263.     
  264.     switch (message)
  265.         {
  266.         case lDrawMsg:
  267.         case lHiliteMsg:
  268.         
  269.             // save the data to avoid locking things down
  270.             if (dataLen > sizeof(theCellContents) )
  271.                 dataLen = sizeof(theCellContents);
  272.             BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
  273.             
  274.             // draw the cell as an icon, but only if we see our magic marker at the front
  275.             if ( (theCellContents.firstMarker == '≈') && (theCellContents.secondMarker == '≈') )
  276.                 {
  277.                 // center the icon rect on the list with a top margin of 10 pixels
  278.                 iconRect.top = theRect->top + 10;
  279.                 iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
  280.                 iconRect.bottom = iconRect.top + 32;
  281.                 iconRect.right = iconRect.left + 32;
  282.                 
  283.                 
  284.                 // draw the icon
  285.                 if (theCellContents.iconSuiteHandle != nil)
  286.                     PlotIconSuite(&iconRect,
  287.                             ttNone, (select) ? ttSelected: ttNone,
  288.                             theCellContents.iconSuiteHandle);
  289.                             
  290.                 // Get the general area under the icon in which to draw the label
  291.                 iconRect.left = theRect->left + 2;
  292.                 iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
  293.                 iconRect.top = iconRect.bottom + 2;
  294.                 iconRect.bottom = theRect->bottom;
  295.     
  296.                 // use a nice small font for the label            
  297.                 TextFont(applFont);
  298.                 TextSize(9);
  299.                 
  300.                     {
  301.                     short        labelWidth;
  302.                     short        rectWidth;
  303.                     short        labelHeight;
  304.                     FontInfo    theInfo;
  305.                 
  306.                     // Get rid of any text that was there before
  307.                     EraseRect(&iconRect);
  308.                     iconRect.top += 2;
  309.                     
  310.                     // compute the height of the label                    
  311.                     GetFontInfo(&theInfo);
  312.                     labelHeight = theInfo.ascent + theInfo.leading;
  313.                     
  314.                     // compute where to draw the text
  315.                     iconRect.bottom = iconRect.top + labelHeight;
  316.                     rectWidth = iconRect.right-iconRect.left;
  317.                     
  318.                     // truncate the string to fit within the box
  319.                     TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
  320.                     
  321.                     // compute the new width of the string
  322.                     labelWidth = StringWidth(theCellContents.iconName);
  323.                     
  324.                     // center the string, draw it
  325.                     iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
  326.                     MoveTo(iconRect.left, iconRect.bottom);
  327.                     DrawString(theCellContents.iconName);
  328.                     
  329.                     if (select)
  330.                         {
  331.                         // compute right and lower edge of box bounding the text we just drew
  332.                         iconRect.right = iconRect.left + labelWidth;
  333.                         iconRect.bottom += theInfo.descent;
  334.                         
  335.                         // outset it, and invert it to select it
  336.                         InsetRect(&iconRect, -1, -1);
  337.                         hiliteMode = LMGetHiliteMode();
  338.                         BitClr(&hiliteMode, pHiliteBit);
  339.                         LMSetHiliteMode(hiliteMode);
  340.                         InvertRect(&iconRect);
  341.                         }
  342.                     }
  343.                     
  344.                 TextFont(applFont);
  345.                 TextSize(0);
  346.                 }
  347.             else
  348.                 {
  349.                 // how boring!  It's only text
  350.                 FontInfo    theInfo;
  351.                 Rect        ourRect;
  352.                 short        cellWidth;
  353.                 
  354.                 // add a margin to the rectangle
  355.                 ourRect = *theRect;
  356.                 ourRect.left += 4;
  357.                 --ourRect.right;
  358.                 cellWidth = ourRect.right - ourRect.left;
  359.                 
  360.                 // erase the rectangle
  361.                 GetFontInfo(&theInfo);
  362.                 EraseRect(theRect);
  363.                 MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
  364.                 
  365.                 // hey, you can't park that string here -- it's too big!
  366.                 if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
  367.                     {
  368.                     // condense the text first
  369.                     TextFace(condense);
  370.                     
  371.                     // then truncate afterwards
  372.                     TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
  373.                     }
  374.                     
  375.                 // those darn other languages!
  376.                 if (GetSysJust() == teJustRight)
  377.                     Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
  378.                     
  379.                 OldDrawText((Ptr) &theCellContents, 0, dataLen);
  380.                 
  381.                 // if selected, invert it
  382.                 if (select)
  383.                     {
  384.                     hiliteMode = LMGetHiliteMode();
  385.                     BitClr(&hiliteMode, pHiliteBit);
  386.                     LMSetHiliteMode(hiliteMode);
  387.                     InvertRect(theRect);
  388.                     }
  389.                     
  390.                 // normal text again
  391.                 TextFace(normal);
  392.                 }
  393.                 
  394.             break;
  395.             
  396.         } // switch
  397.         
  398. } // LDEF
  399.